package com.qi.pay.demo;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.HttpStatus;

import com.google.gson.Gson;
import com.qi.pay.demo.model.ApiRequest;
import com.qi.pay.demo.model.ApiResponse;
import com.qi.pay.demo.model.PayQueryResponseBody;
import com.qi.pay.demo.util.HttpUtils;
import com.qi.pay.demo.util.HttpUtils.HttpResponse;
import com.qi.pay.demo.util.SignUtils;

/**
 * 
 * @param <T>	request
 * @param <E>	response
 */
public class PayHelper<T, E> {
	
	private static final Gson GSON = new Gson();
	
	public ApiResponse<E> post(String path, ApiRequest<T> request, Class<E> clazz) {
		ApiResponse<E> apiResponse = null;
		Map<String, String> headerMap = new HashMap<String, String>();
		String requestContent = GSON.toJson(request);
		String sign = SignUtils.createSign(requestContent, Constants.SECRET);
		headerMap.put(Constants.SIGN_HEADER_NAME, sign);
		HttpResponse httpResponse = null;
		try {
			httpResponse = HttpUtils.doPost(Constants.URL + path, requestContent, headerMap, null, null);
		} catch (IOException e) {
			e.printStackTrace();
			apiResponse = new ApiResponse<E>();
			apiResponse.setFail(true);
			apiResponse.setStatus(-1);
			apiResponse.setMessage("系统异常," + e.getMessage());
			return apiResponse;
		}
		if(httpResponse != null) {
			apiResponse = PayHelper.fromJsonObject(httpResponse.getResponseBody(), clazz);
			if(httpResponse.getStatusCode() != HttpStatus.SC_OK) {
				apiResponse.setFail(true);
				apiResponse.setStatus(-1);
				apiResponse.setMessage("平台错误, 状态码=" + httpResponse.getStatusCode());
			}else {
				if(!apiResponse.validTimestamp()) {
					apiResponse.setFail(true);
					apiResponse.setStatus(-1);
					apiResponse.setMessage("无效平台端的时间戳！");
				}
				if(apiResponse.getStatus() == 0) {
					String clientSign = SignUtils.createSign(httpResponse.getResponseBody(), Constants.SECRET);
					String serverSign = httpResponse.getHeaderMap().get(Constants.SIGN_HEADER_NAME);
					if(!clientSign.equals(serverSign)) {
						apiResponse.setFail(true);
						apiResponse.setStatus(-1);
						apiResponse.setMessage("无效平台端的签名！");
					}
				}
			}
		}
		return apiResponse;
	}
	
	public static <T> ApiResponse<T> fromJsonObject(String reader, Class<T> clazz) {
	    Type type = new ParameterizedTypeImpl(ApiResponse.class, new Class[]{clazz});
	    return GSON.fromJson(reader, type);
	}

	public static <T> ApiResponse<List<T>> fromJsonArray(String reader, Class<T> clazz) {
	    Type listType = new ParameterizedTypeImpl(List.class, new Class[]{clazz});
	    Type type = new ParameterizedTypeImpl(ApiResponse.class, new Type[]{listType});
	    return GSON.fromJson(reader, type);
	}
	
	
	@SuppressWarnings("rawtypes")
	static class ParameterizedTypeImpl implements ParameterizedType {
	   
		private final Class raw;
	    private final Type[] args;

	    public ParameterizedTypeImpl(Class raw, Type[] args) {
	        this.raw = raw;
	        this.args = args != null ? args : new Type[0];
	    }

	    @Override
	    public Type[] getActualTypeArguments() {
	        return args;
	    }

	    @Override
	    public Type getRawType() {
	        return raw;
	    }

	    @Override
	    public Type getOwnerType() {
	        return null;
	    }
	}
	
	public static void main(String[] args) {
		String reader = "{\"body\":{\"status\":1},\"status\":0,\"merchantId\":\"7JTY14RUGZ5S\",\"timestamp\":\"1526112028534\"}";
		ApiResponse<PayQueryResponseBody> apiResponse = PayHelper.fromJsonObject(reader, PayQueryResponseBody.class);
		System.out.println(apiResponse);
	}
}
